<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2023-07-04 15:23:57
// |@----------------------------------------------------------------------
// |@LastEditTime : 2023-11-21 17:05:36
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : Menu.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2023 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------
namespace app\login\logic;

use think\admin\extend\DataExtend;
use think\admin\Logic;

/**
 * 菜单逻辑类，用于实现登陆获取菜单的业务逻辑操作。
 */
class Menu extends Logic
{
    /**
     * 获取系统菜单列表和相关权限信息
     * @param int|null $user_id 用户ID
     * @param array $role_list 用户所属角色列表
     * @return array 菜单和权限信息数组
     */
    public function getMenuList(?int $user_id, array $role_list): array
    {
        if ($user_id !== null && $user_id !== 1) {
            // 非超级管理员用户需要根据角色和权限获取自己的菜单列表
            $auth = $this->modelSystemAuth->whereIn('role_id', $role_list)->find();
            if (!$auth) {
                // 如果没有对应的权限，则无法获取菜单
                return $this->json(LOGIN_ERROR, lang('user.get_menu_list_fail'));
            }
            // 使用菜单 ID 列表来过滤菜单数据，并按照 sort 字段排序
            $menu_list = $this->modelSystemMenu->whereIn('id', json_decode($auth->menu_id_list))->order('sort')->select();
        } else {
            // 超级管理员可以获取所有菜单数据，并按照 sort 字段排序
            $menu_list = $this->modelSystemMenu->order('sort')->select();
        }
        // 格式化菜单列表，方便前端渲染菜单和路由
        $menus = $this->formatMenuList($menu_list);
        // 获取菜单权限列表，方便后续接口权限控制
        $permissions = $this->getMenuPermissions($menu_list);
        // 返回菜单列表数据
        return $this->json(SUCCESS, lang('user.get_menu_list_success'), [
            'menu' => DataExtend::arr2tree(array_values($menus)),
            'permissions' => array_values($permissions['api_list']),
            'api_auth' => array_values($permissions['api_auth']),
        ]);
    }
    
    /**
     * 格式化菜单列表数据
     * @param \think\Collection|array $menu_list 菜单列表
     * @return array 格式化后的菜单数据
     */
    private function formatMenuList(\think\Collection $menu_list): array
    {
        $menus = [];
        foreach ($menu_list as $v){
            // 筛选非按钮类型的菜单
            if ($v['type'] != 'button'){
                // 构造菜单的 meta 信息，包含标题、图标、类型、颜色、激活状态等
                $meta = [
                    'title' => $v['title'],
                    'icon' => $v['icon'],
                    'type' => $v['type'],
                    'color' => $v['color'],
                    'active' => $v['active'],
                    'hidden' => $v['hidden'] == 1 ? false : true,
                    'hidden_breadcrumb' => $v['hidden_breadcrumb'] == 1 ? false : true,
                    'affix' => $v['affix'] == 1 ? true : false,
                ];
                // 构造菜单信息，包含菜单 ID、父级菜单 ID、名称、路径、meta 信息、组件地址等
                $menus[$v['id']] = [
                    'id' => $v['id'],
                    'pid' => $v['pid'],
                    'name' => $v['name'],
                    'path' => $v['path'],
                    'meta' => $meta,
                    'component' => $v['component'],
                ];
            }
        }
        // 过滤空值菜单项，返回格式化后的菜单数据
        return  DataExtend::arrfilterEmptyValues($menus);
    }
    
    /**
     * 获取菜单的接口权限列表
     * @param \think\Collection|array $menu_list 菜单列表
     * @return array 权限数据，包括接口权限和接口授权信息
     */
    private function getMenuPermissions(\think\Collection $menu_list): array
    {
        $permissions = [];
        foreach ($menu_list as $v){
            // 解析菜单的接口权限列表，加入权限数据中
            $v['api_list'] = !empty($v['api_list']) ? json_decode($v['api_list'], true) : [];
            foreach ($v['api_list'] as $vs){
                $permissions['api_list'][$vs['url']] = $vs['code'];
                $permissions['api_auth'][$vs['url']] = $vs;
            }
        }

        // 返回权限数据
        return $permissions;
    }
}